/********************************************************************************************
*            Copyright (c) 2013. All Rights Reserved.
*
*
* 文件名称:   gnss_task.h
* 描    述:	 
* 当前版本:   V1.0
* 日    期:   2020/12/30
* 创 建 人:   杨小珛
* 
*********************************************************************************************/
#ifndef GNSS_TASK_H
#define GNSS_TASK_H

/* FreeRTOS Kernel includes. */
#include "os_app.h"

/***************************** 格式说明 ****************************************
推荐定位信息(RMC)
    $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
    <1> UTC时间，hhmmss(时分秒)格式
    <2> 定位状态，A=有效定位，V=无效定位
    <3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
    <4> 纬度半球N(北半球)或S(南半球)
    <5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)
    <6> 经度半球E(东经)或W(西经)
    <7> 地面速率(000.0~999.9节，前面的0也将被传输)
    <8> 地面航向(000.0~359.9度，以真北为参考基准，前面的0也将被传输)
    <9> UTC日期，ddmmyy(日月年)格式
    <10> 磁偏角(000.0~180.0度，前面的0也将被传输)
    <11> 磁偏角方向，E(东)或W(西)
    <12> 模式指示(仅NMEA0183 3.00版本输出，A=自主定位，D=差分，E=估算，N=数据无效)

GGA格式
    $GPGGA 语句包括17个字段：语句标识头，世界时间，纬度，纬度半球，经度，经度半球，定位质量指示，
                             使用卫星数量，水平精确度，海拔高度，高度单位，大地水准面高度，高度单位，
                             差分GPS数据期限，差分参考基站标号，校验和结束标记(用回车符<CR>和换行符<LF>)，
                             分别用14个逗号进行分隔。该数据帧的结构及各字段释义如下：
    $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx<CR><LF>
    $GPGGA：起始引导符及语句格式说明(本句为GPS定位数据)；
    <1>  UTC时间，格式为hhmmss.sss；
    <2>  纬度，格式为ddmm.mmmm(第一位是零也将传送)；
    <3>  纬度半球，N或S(北纬或南纬)
    <4>  经度，格式为dddmm.mmmm(第一位零也将传送)；
    <5>  经度半球，E或W(东经或西经)
    <6>  定位质量指示，0=定位无效，1=定位有效；
    <7>  使用卫星数量，从00到12(第一个零也将传送)
    <8>  水平精确度，0.5到99.9
    <9>  天线离海平面的高度，-9999.9到9999.9米
    M    指单位米
    <10> 大地水准面高度，-9999.9到9999.9米
    M    指单位米
    <11> 差分GPS数据期限(RTCM SC-104)，最后设立RTCM传送的秒数量
    <12>  差分参考基站标号，从0000到1023(首位0也将传送)。
    *    语句结束标志符
    xx    从$开始到*之间的所有ASCII码的异或校验和
    <CR>   回车
    <LF>   换行
*******************************************************************************/
// ----------------------------------------------------------------------------
#define     GNSS_GEMU   OS_GNSS_MODULE_MODEL            //常规的模块
#define     GNSS_QXWZ   ( !GNSS_GEMU )                  //千寻模块

#define		MSG_GPS_SAM_REV_WAIT_TIME ( 5000 )          // 等待消息邮箱的时间
#define     GNSS_RECV_DATA_RUN_WAIT_TIME    ( 5000 )
#define     GNSS_RECV_DATA_SLEEP_WAIT_TIME      ( 1000 )

#define		GNSS_POWER_PIN         ( 2 )                /*电源控制IO口*/
#define		GNSS_UART_PORT         ( 2 )                /*GNSS串口*/

#define     GNSS_DATA_ERR          0x0000
#define     GNSS_DATA_OK           0x0001

#define     GNSS_GMC_ERR           0x0000
#define     GNSS_GMC_OK            0x0001

#define     GNSS_GGA_ERR           0x0000
#define     GNSS_GGA_OK            0x0001

#define     GNSS_GSA_ERR           0x0000
#define     GNSS_GSA_OK            0x0001

#define     GNSS_GSV_ERR           0x0000
#define     GNSS_GSV_OK            0x0001

// ----------------------------------------------------------------------------
#define     RMC_UTC_POS            1        // UTC(hhmmss)逗号位置
#define     RMC_PFS_POS            2        // 定位标志(A=定位，V=未定位)逗号位置
#define     RMC_LAT_POS            3        // 纬度(ddmm.mmmm度分)逗号位置
#define     RMC_NSI_POS            4        // 北纬南纬(N/S)标志逗号位置
#define     RMC_LON_POS            5        // 经度(dddmm.mmmm度分)逗号位置
#define     RMC_EWI_POS            6        // 东经西经(E/W)标志逗号位置
#define     RMC_SPD_POS            7        // 相对位移速度(000.0~999.9节)逗号位置
#define     RMC_ORI_POS            8        // 相对位移方向(000.0~359.9度)逗号位置
#define     RMC_DAT_POS            9        // UTC日期(ddmmyy)逗号位置
#define     RMC_AUNT_POS           10       // 磁偏角(000.0~180.0度)逗号位置
#define     RMC_MVV_POS            11       // 磁偏角方向(E/W)逗号位置
#define     RMC_MVI_POS            12       // 模式指示(A=自主定位，D=差分，E=估算，N=数据无效)逗号位置

// ----------------------------------------------------------------------------
#define     GGA_UTC_POS         1        // UTC(hhmmss.sss)逗号位置
#define     GGA_LAT_POS         2        // 纬度(ddmm.mmmm度分)逗号位置
#define     GGA_NSI_POS         3        // 北纬南纬标志逗号位置
#define     GGA_LON_POS         4        // 经度(dddmm.mmmm度分)逗号位置
#define     GGA_EWI_POS         5        // 东经西经标志逗号位置
#define     GGA_PFS_POS         6        // 定位标志(0=未定位，1=实时GPS， 2=查分GPS)逗号位置
#define     GGA_SAT_POS         7        // 卫星数(00~12)逗号位置
#define     GGA_HDOP_POS        8        // 水平精度因子(0.5~99.9)逗号位置
#define     GGA_ALT_POS         9        // 天线高程(-9999.9~99999.9m)逗号位置
#define     GGA_AUNT_POS        10       // 天线高程单位逗号位置
#define     GGA_GEO_POS         11       // 大地海平面高度(-999.9~9999.9m)逗号位置
#define     GGA_GUNT_POS        12       // 大地海平面高度单位逗号位置
#define     GGA_DIFF_AGE_POS    13       // 差分GPS数据年龄逗号位置
#define     GGA_DIFF_ID_POS     14       // 差分基准站号(0000~1023)逗号位置

// ----------------------------------------------------------------------------
#define     GSA_MODE_POS        2        // 定位模式
#define     GSA_PDOP_POS       15       // 位置精度因子


/***************GPS模块天线状态*********************************/
#define     GPS_ANT_OK               0x00  // GPS天线正常
#define     GPS_ANT_SHORT            0x01  // GPS天线短路
#define     GPS_ANT_OPEN             0x02  // GPS天线断路
#define     GPS_ANT_FAULT            0x04  // GPS天线故障
#define     GPS_ANT_NOT_Stability   0x08  // GPS天线状态不稳定 AD数据连续采样不一致。

/***************GPS模块电源状态********************************/
#define     GPS_MODEL_CLOSE		 0x00   // GPS模块电源关闭
#define     GPS_MODEL_OPEN		 	 0x01   // GPS模块电源打开

#define     GPS_MODEL_OK            0x00  // GPS模块正常
#define     GPS_MODEL_ERROR         0x01  // GPS模块故障
#define     GPS_MODEL_DATA_ERROR    0x02  // GPS模块数据异常
#define     GPS_MODEL_POSI_ERROR    0x03  // GPS模块定位异常
#define     GPS_MODEL_POSI_OK       0x04  // GPS模块定位成功

#define     GPS_MODEL_PWR_ON        0x00  // GPS电源打开
#define     GPS_MODEL_PWR_OFF       0x01  // GPS电源关闭

/*****************经纬度标定位置********************************/
#define		LONGITUDE_L         0x433E24  // 以0.001分为单位  中国地图经度坐标(左侧)--东经73.44695998度
#define		LONGITUDE_R         0x7BAB60  // 中国地图经度坐标(右侧)--东经135.07925度
#define		LATITUDE_U          0x31086C  // 中国地图纬度坐标(上侧)--北纬53.55749899度
#define		LATITUDE_D          0x10A07C  // 中国地图纬度坐标(下侧)--北纬18.160896度

/*****************GNSS数据有效性判断****************************/
#define     GNSS_MAX_SPEED      2000      // GNSS 最大速度值 200km/h
#define     GNSS_MIN_SPEED      30        // GNSS 最小速度值 3km/h
#define     GNSS_VALID_SPEED_COUNT 3      // GNSS 有效速度计数     
#define     GNSS_VALID_SAT_NUM 3          // GNSS 有效卫星数量 3颗 (为了兼容千寻模块由之前的6修改为3)
#define     GNSS_POS_PDOP       10        // GNSS 定位精度 （防止精度不够，由之前的6修改为10）

#define     GNSS_AGPS_NUM       8         // AGPS 辅助定位最小定位颗数
/****************GNSS模块的状态*********************************/
typedef enum
{
	GNSS_STA_INIT = 0x00,
    GNSS_MON_ERR,        // GPS 模块异常
    GNSS_MOD_OK,      	  // GPS 模块正常
    GNSS_POS_OK,         // GPS 定位正常
} gnss_mod_state_e;

/**
 * NMEA packets type which parsed and generated by library
 */
enum nmeaPACKTYPE
{
    GPNON   = 0x0000,     /**< Unknown packet type. */
	
    GPGGA   = 0x000001,   /**< GGA - Essential fix data which provide 3D location and accuracy data. */
    GPGSA   = 0x000002,   /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
    GPGSV   = 0x000004,   /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
    GPRMC   = 0x000008,   /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
    GPVTG   = 0x000010,    /**< VTG - Actual track made good and speed over ground. */
	GPGLL   = 0x000020,   /**< GLL - 地理位置 经纬度 */
    GPZDA   = 0x000040,   /**< ZDA - 时间和日期 */
    GPTXT   = 0x000080,   /**< TXT - 产品信息、天线状态、闰秒等 */
	
	GNGGA   = 0x000100,   /**< GGA - Essential fix data which provide 3D location and accuracy data. */
    GNGSA   = 0x000200,   /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
    GNGSV   = 0x000400,   /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
    GNRMC   = 0x000800,   /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
    GNVTG   = 0x001000,   /**< VTG - Actual track made good and speed over ground. */
	GNGLL   = 0x002000,   /**< GLL - 地理位置 经纬度 */
    GNZDA   = 0x004000,   /**< ZDA - 时间和日期 */
    GNTXT   = 0x008000,   /**< TXT - 产品信息、天线状态、闰秒等 */
	
	BDGGA   = 0x010000,   /**< GGA - Essential fix data which provide 3D location and accuracy data. */
    BDGSA   = 0x020000,   /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
    BDGSV   = 0x040000,   /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
    BDRMC   = 0x080000,   /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
    BDVTG   = 0x100000,    /**< VTG - Actual track made good and speed over ground. */
	BDGLL   = 0x200000,   /**< GLL - 地理位置 经纬度 */
    BDZDA   = 0x400000,   /**< ZDA - 时间和日期 */
    BDTXT   = 0x800000,   /**< TXT - 产品信息、天线状态、闰秒等 */
};

/*****************  Time strcuture use bcd ************************************/
typedef struct //全部采用BCD码
{
    unsigned char     year;      /* Year value - 0x00-0x99             */
    unsigned char     month;     /* Month value - 0x01-0x12            */
    unsigned char     day;       /* Day of the month value - 0x01-0x31 */
    unsigned char     hour;      /* Hour value - 0x00-0x23             */
    unsigned char     minute;    /* Minute value - 0x00-0x59           */
    unsigned char     second;    /* Second value - 0x00-0x59           */
    unsigned char     reserve1;
    unsigned char     reserve2;
} time_bcd_struct;

typedef struct
{
    volatile    uint8_t     is_lbs_type;             // 是否为LBS定位 及类型 00 非LBS坐标  !=0 LBS定位类型 
    volatile    uint8_t     is_valid;                // 是否有效标志
    volatile    uint8_t     gga_fs;                  // 定位质量
    volatile    uint8_t     sat_num;                 // 有效卫星数量
    volatile    uint8_t     pos_flag;                // 定位标志：0-不定位，1-定位
    volatile    uint8_t     pos_mode;                // 定位模式：1-定位不可用，2=2D ，3=3D
    volatile    uint8_t     pdop;                    // 定位精度因子
    volatile    uint8_t     nsi;                     // 纬度标志
    volatile    uint8_t     ewi;                     // 精度标志
    volatile    uint8_t     agps_num;                // 辅助定位卫星颗数
    volatile    uint32_t    latitude;                // 纬度，正数为北纬，精确到0.00001分
    volatile    uint32_t    longitude;               // 经度，正数为东经，精确到0.00001分
    volatile    int32_t     altitude;                // 海拔，以米为单位
    volatile    uint16_t    speed;                   // 速度，0.1km/h（以记录仪为主）
    volatile    uint16_t    direction;               // 方向，0为正北方，顺时针，精度0.1度
    volatile    uint16_t    pos_static;              // 0：无定位  1：静态定位  2：动态定位
    volatile    uint8_t     snr;                     // 信噪比（GSV）
    volatile    uint8_t     gps_total_num_sat;       // GPS可视卫星总数（GSV)
    volatile    uint8_t     valid_gps_total_num_sat; // 有效的GPS可视卫星总数（GSV)
    volatile    uint8_t     bd_total_num_sat;        // BD可视卫星总数（GSV)
    volatile    uint8_t     valid_bd_total_num_sat;  // 有效的BD可视卫星总数（GSV)
    time_bcd_struct  time;                           // 北京时间
} gnss_position_info_struct, *pgnss_position_infostruct;

typedef struct
{
    volatile    uint8_t  gnss_model_status;           //GPRS模块当前的状态
    volatile    uint8_t  gnss_ant_status;             //天线状态
    gnss_position_info_struct  gnss_position_info;    //GPS数据信息
} gnss_info_struct;

/****************************************************************************************
* GNSS串口数据结构体
******************************************************************************************/
#define	GNSS_NMEA_DATA_LEN ( 1024   * 2 ) 

typedef  struct
{
	uint16_t len;
	uint8_t *data;
}gnss_recv_buf_typedef;

#define GNSS_RECV_DATA_QUEUE_DEPTH  ( 35 )

/****************************************************************************************
* GNSS 最后需要存储的经纬度信息
******************************************************************************************/
typedef struct
{   
    volatile    uint32_t    lat;                // 纬度，正数为北纬，精确到0.00001分
    volatile    uint32_t    lng;                // 经度，正数为东经，精确到0.00001分
    volatile    uint32_t    mil;                // 里程，GPS行驶的里程
    volatile    uint32_t    crc;                // CRC
}gnss_save_info_t;

/****************************************************************************************
* GNSS 静态缓存信息
******************************************************************************************/
#define GNSS_STATIC_FILTER_BUF_SUM 60         //GPS静态过滤缓冲区总条数

typedef struct
{
	volatile uint32_t lat;			    //纬度
	volatile uint32_t lon;			    //经度
	volatile uint16_t direction;		//航向
	volatile uint8_t  density_cnt;      //密度计数
	volatile uint8_t  angle_cnt;        //角度计数
}gnss_static_filter_t;

typedef struct
{
	gnss_static_filter_t unit[GNSS_STATIC_FILTER_BUF_SUM];
	volatile uint8_t cnt;
}gnss_static_filter_buf_t;

/****************************************************************************************
* GNSS 车辆静止数据过滤使能 枚举类型
******************************************************************************************/
typedef enum
{
    GNSS_SF_ENABLE = 0x00,        // GNSS 数据过滤使能
    GNSS_SF_DISENABLE,      	  // GNSS 数据过滤失能
} gnss_static_filter_enable_state_e;

/****************************************************************************************
* GNSS 车辆静止数据过滤使能 枚举类型
******************************************************************************************/
typedef enum
{
    GNSS_QXSDK_DISENABLE = 0x00,  // GNSS QXSDK 失能
    GNSS_QXSDK_ENABLE,      	  // GNSS QXSDK 使能
} gnss_qxsdk_enable_state_e;

/** ****************************************************************************
* @remarks       void gnss_data_create_task( unsigned portBASE_TYPE uxPriority )
* @brief         创建GNSS基层数据管理任务
* @param[in]     uxPriority任务优先级；
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_data_create_task( unsigned portBASE_TYPE uxPriority );

/** ****************************************************************************
* @remarks       uint32_t gnss_speed_get( uint32_t *speed )
* @brief         获取GNSS当前的速度
* @param[in]     无
* @param[out]    *speed 当前GNSS的速度 ,不能为空
* @return        pdPASS 数据有效 pdFAIL 数据无效 *speed 当前速度的指针
* @attention     无
*******************************************************************************/
extern uint32_t gnss_speed_get( uint32_t *speed );

/** ****************************************************************************
* @remarks       void gnss_info_now_get( gnss_info_struct *info )
* @brief         获取GNSS最新数据数据信息
* @param[in]     无
* @param[out]    *info GNSS数据的目标地址
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_info_now_get( gnss_info_struct *info );

/** ****************************************************************************
* @remarks       void gnss_info_old_get( gnss_info_struct *info )
* @brief         获取GNSS历史数据
* @param[in]     无
* @param[out]    *info GNSS数据的目标地址
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_info_old_get( gnss_info_struct *info );

/** ****************************************************************************
* @remarks       uint32_t gnss_ant_atate_get( void )
* @brief         获取GNSS模块天线的状态
* @param[in]     无
* @param[out]    无
* @return        GPS_ANT_OK GPS天线正常 ， GPS_ANT_SHORT GPS天线短路 ，GPS_ANT_OPEN GPS天线断路 ，PS_ANT_FAULT GPS天线故障 ，PS_ANT_NOT_Stability GPS天线状态不稳定 AD数据连续采样不一致。
* @attention     无
*******************************************************************************/
extern uint32_t gnss_ant_atate_get( void );

/** ****************************************************************************
* @remarks       uint32_t gnss_status_get( void )
* @brief         获取GNSS模块的状态
* @param[in]     无
* @param[out]    无
* @return        GNSS_ANT_ERR 天线异常  GNSS_MOD_OK 模块正常 GNSS_POS_OK 定位正常
* @attention     无
*******************************************************************************/
extern uint32_t gnss_status_get( void );

/** ****************************************************************************
* @remarks       void gnss_qxwz_data_update_buf(uint8_t *buf, uint16_t len)
* @brief         GNSS UART数据更新数据包
* @param[in]     *buf数据地址；
* @param[in]     len数据长度；
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_qxwz_data_update_buf(uint8_t *buf, uint16_t len);

/** ****************************************************************************
* @remarks       void gnss_info_flash_read( void )
* @brief         获取GNSS FLASH 存储的数据
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_info_flash_read( gnss_info_struct *gnss );

/** ****************************************************************************
* @remarks       void gnss_info_flash_read( void )
* @brief         获取GNSS FLASH 存储的数据
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_info_flash_write( void );

/** ****************************************************************************
* @remarks       uint32_t gnss_mileage_get( void )
* @brief         获取GNSS 计算累积里程
* @param[in]     无
* @param[out]    无
* @return        GNSS里程 单位，米
* @attention     无
*******************************************************************************/
extern uint32_t gnss_mileage_get( void );

/** ****************************************************************************
* @remarks       void gnss_mileage_set( void )
* @brief         设置GNSS 计算累积里程
* @param[in]     mil  设置当前车辆运行的距离，单位米
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_mileage_set( uint32_t mil );

/** ****************************************************************************
* @remarks       static void gnss_sys_time_set( rtc_struct *rtc )
* @brief         获取GNSS 设置系统时间
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_sys_time_set( void );

/** ****************************************************************************
* @remarks       uint32_t gnss_static_filter_count_get( void )
* @brief         获取GNSS 静态数据过滤次数
* @param[in]     无
* @param[out]    无
* @return        过滤次数
* @attention     无
*******************************************************************************/
extern uint32_t gnss_static_filter_count_get( void );

/** ****************************************************************************
* @remarks       gnss_static_filter_enable_state_e gnss_static_filter_enable_state_get( void ) 
* @brief         获取GNSS 静止数据过滤使能状态
* @param[in]     无
* @param[out]    无
* @return        返回使能状态  GNSS_SF_ENABLE 使能， GNSS_SF_DISENABLE 失能
* @attention     无
*******************************************************************************/
extern gnss_static_filter_enable_state_e gnss_static_filter_enable_state_get( void );

/** ****************************************************************************
* @remarks       void gnss_static_filter_enable_state_get( gnss_static_filter_enable_state_e st ) 
* @brief         设置GNSS 静止数据过滤使能状态
* @param[in]     st设置使能状态；GNSS_SF_ENABLE 使能， GNSS_SF_DISENABLE 失能
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_static_filter_enable_state_set( gnss_static_filter_enable_state_e st );

/** ****************************************************************************
* @remarks       static void gnss_lbs_wifiscan_position_read( void )
* @brief         LBS wifiscan 辅助定位数据读取
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_lbs_wifiscan_position_read( void );

/** ****************************************************************************
* @remarks       uint8_t gnss_lbs_position_type_read( void )
* @brief         GNSS LBS 辅助定位类型
* @param[in]     无
* @param[out]    无
* @return        定位类型，0:没有得到定位结果;1:gps 定位结果;2:wifi定位结果;3:混合定位 结果;4:基站定位结果;5:其他--
* @attention     无
*******************************************************************************/
extern uint8_t gnss_lbs_position_type_read( void );

/** ****************************************************************************
* @remarks       void gnss_lbs_position_type_clear( void )
* @brief         清除掉 GNSS LBS 辅助定位类型标识
* @param[in]     无
* @param[out]    无
* @return        无
* @attention     无
*******************************************************************************/
extern void gnss_lbs_position_type_clear( void );

extern uint8_t gnss_lbs_position_once_state_read( void );

/** ****************************************************************************
* @remarks       uint8_t gnss_agps_num_get( void )
* @brief         获取AGPS辅助卫星数量
* @param[in]     无
* @param[out]    无
* @return        卫星数量
* @attention     无
*******************************************************************************/
extern uint8_t gnss_agps_num_get( void );
#endif

